package com.algomypractice.array;

import java.util.ArrayList;

/**
 * @author: ZhouBert
 * @date: 2019/6/3
 * @description: 模拟 ArrayList 具有动态扩容
 */
public class GenericArray<T> {

	/**
	 * 存储数据
	 */
	private T[] data;
	/**
	 * 当前元素个数
	 */
	private int size;

	/**
	 * 根据传入容量，构造Array
	 *
	 * @param capacity
	 */
	public GenericArray(int capacity) {
		///java 不允许直接创建 泛型数组 ——> 1.先创建Object[] 再显式转为T[];2.先创建Object[],再获取单个时显式转为T
		///https://jingyan.baidu.com/article/b907e627d0dbd846e7891cf1.html
		///new T [capacity]; false
		data = (T[]) new Object[capacity];
		size = 0;
	}

	/**
	 * 无参构造函数
	 */
	public GenericArray() {
		this(10);
	}

	/**
	 * 获取数组容量
	 *
	 * @return
	 */
	public int getCapacity() {
		return data.length;
	}

	/**
	 * 获取当前元素个数
	 *
	 * @return
	 */
	public int count() {
		return size;
	}

	/**
	 * 判断数组是否为空
	 *
	 * @return
	 */
	public boolean isEmpty() {
		return size == 0;
	}

	/**
	 * 修改 index 位置的元素
	 *
	 * @param index
	 * @param e
	 */
	public void set(int index, T e) {
		checkIndex(index);
		data[index] = e;
	}

	/**
	 * 获取对应 index 位置的元素
	 *
	 * @param index
	 * @return
	 */
	public T get(int index) {
		checkIndex(index);
		return data[index];
	}

	/**
	 * 查看数组是否包含元素e
	 *
	 * @param e
	 * @return
	 */
	public boolean contains(T e) {
		for (int i = 0; i < size; i++) {
			if (e.equals(data[i])) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 获取对应元素的下标, 未找到，返回 -1
	 *
	 * @param e
	 * @return
	 */
	public int find(T e) {
		int result = -1;
		for (int i = 0; i < size; i++) {
			if (e.equals(data[i])) {
				result = i;
				return result;
			}
		}
		return result;
	}


	/**
	 * 在 index 位置，插入元素e, 时间复杂度 O(m+n)
	 *
	 * @param index
	 * @param e
	 */
	public void add(int index, T e) {
		checkIndex(index);
		///当长度等于
		if (data.length == size) {
			T[] dataNew = (T[]) new Object[size * 2];
			for (int i = 0; i < size; i++) {
				dataNew[i] = data[i];
			}
			data = dataNew;
		}
		data[index] = e;
		size++;
	}

	/**
	 * 向数组头插入元素
	 * @param e
	 */
	public void addFirst(T e) {
		this.add(0,e);
	}

	// 向数组尾插入元素
	public void addLast(T e) {

	}

	// 删除 index 位置的元素，并返回
	public T remove(int index) {
		return null;
	}

	// 删除第一个元素
	public T removeFirst() {
		return null;
	}

	// 删除末尾元素
	public T removeLast() {
		return null;
	}

	// 从数组中删除指定元素
	public void removeElement(T e) {

	}

	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append(String.format("Array size = %d, capacity = %d \n", size, data.length));
		builder.append('[');
		for (int i = 0; i < size; i++) {
			builder.append(data[i]);
			if (i != size - 1) {
				builder.append(", ");
			}
		}
		builder.append(']');
		return builder.toString();
	}


	// 扩容方法，时间复杂度 O(n)
	private void resize(int capacity) {

	}

	/**
	 * 检查 索引合法性
	 *
	 * @param index
	 */
	private void checkIndex(int index) {
		if (index < 0 || index > size) {
			System.err.println("index 不合法");
		}
	}

	private void checkIndexForRemove(int index) {

	}

	public static void main(String[] args) {
		GenericArray<Integer> array = new GenericArray<>(1);
		array.add(0,1);
		array.add(1,2);
		System.out.println(array);
		ArrayList<Integer> arrayList = new ArrayList<>();
		arrayList.add(19,1);
	}
}
